﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace ROrganizer.Client
{
    internal class ImdbSerializer
    {
        public ImdbEntry[] Deserialize(XDocument document)
        {
            var query = from element in document.Root.Elements()
                        select ImdbSerializer.Deserialize(element);

            return query.ToArray();
        }

        public ImdbEntry Deserialize(XDocument document, string file)
        {
            var query = from element in document.Root.Elements()
                        where element.Element("File").Value == file
                        select ImdbSerializer.Deserialize(element);

            return query.FirstOrDefault();
        }

        private static ImdbEntry Deserialize(XElement element)
        {
            return new ImdbEntry
            {
                File = element.Element("File").Value,
                InfoTimestamp = DateTime.Parse(element.Element("InfoTimestamp").Value).ToUniversalTime(),
                Info = new ImdbInfo
                {
                    Id = element.Element("Id").Value,
                    Title = element.Element("Title").Value,
                    Rating = String.IsNullOrWhiteSpace(element.Element("Rating").Value) ? default(short?) : Int16.Parse(element.Element("Rating").Value),
                    Published = String.IsNullOrWhiteSpace(element.Element("Published").Value) ? default(DateTime?) : DateTime.Parse(element.Element("Published").Value),
                    Tagline = element.Element("Tagline").Value,
                    Plot = element.Element("Plot").Value,
                    Genres = element.Elements("Genre").Select(x => x.Value).ToArray(),
                    Keywords = element.Elements("Keyword").Select(x => x.Value).ToArray()
                }
            };
        }

        public void Update(XDocument document, params ImdbEntry[] entries)
        {
            foreach (var entry in entries)
            {
                var element = document.Root.Elements().FirstOrDefault(x => x.Element("File").Value == entry.File);
                var created = ImdbSerializer.Serialize(entry);

                if (element != null)
                {
                    element.ReplaceWith(created);
                }
                else
                {
                    document.Root.Add(created);
                }
            }
        }

        private static XElement Serialize(ImdbEntry entry)
        {
            return new XElement("HashEntry",
                        new XElement("File", new XCData(entry.File)),
                        new XElement("InfoTimestamp", entry.InfoTimestamp),
                        new XElement("Id", entry.Info.Id),
                        new XElement("Title", new XCData(entry.Info.Title)),
                        new XElement("Rating", !entry.Info.Rating.HasValue ? String.Empty : entry.Info.Rating.Value.ToString()),
                        new XElement("Published", !entry.Info.Published.HasValue ? String.Empty : entry.Info.Published.Value.ToString()),
                        new XElement("Tagline", new XCData(entry.Info.Tagline)),
                        new XElement("Plot", new XCData(entry.Info.Plot)),
                        from genre in entry.Info.Genres
                        select new XElement("Genre", genre),
                        from keyword in entry.Info.Keywords
                        select new XElement("Keyword", keyword));
        }
    }
}
